package com.alcatel_lucent.coff.model

import org.apache.commons.io.HexDump
import org.apache.commons.lang3.SystemUtils
import org.apache.commons.lang3.builder.ToStringBuilder
import org.apache.commons.lang3.builder.ToStringStyle

import static org.apache.commons.lang3.SystemUtils.LINE_SEPARATOR

import java.text.DateFormat

/**
 * Created with IntelliJ IDEA.
 * User: guoshunw
 * Date: 13-4-12
 * Time: 下午2:30
 * To change this template use File | Settings | File Templates.
 */
abstract class BaseEntity {
    static final ToStringStyle style = new MyToStringStyle()

    public static final Collection<String> excludeFieldNames = ['iSection','usClass']

    @Override
    String toString() {
        ToStringBuilder.reflectionToString(this, style)
    }

    static class MyToStringStyle extends ToStringStyle {

        MyToStringStyle() {
            super()
            contentStart = '['

            fieldSeparator = "${LINE_SEPARATOR}  "
            fieldSeparatorAtStart = true

            useShortClassName = true

            contentEnd = "${LINE_SEPARATOR}]"
        }

        @Override
        protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
//            println "fieldName = ${fieldName}, value=${value}"

            if (value instanceof Number && !excludeFieldNames.contains(fieldName)) {
                int size = 4

                if (value instanceof Integer) {
                    size = 8
                }
                if (value instanceof Long) {
                    size = 16
                }

                String formatStr = "%0${size}X"
                value = String.format(formatStr, value)
            }

            if (value instanceof Date) {

                DateFormat dFmt = DateFormat.getDateTimeInstance DateFormat.FULL, DateFormat.MEDIUM
                int oriNum = (value as Date).getTime() / 1000
                value = String.format '%08X(%s)', oriNum, dFmt.format(value)
            }


            if (value instanceof byte[]) {
                OutputStream os = new ByteArrayOutputStream()
                HexDump.dump(value, 0, os, 0)
                os.close()
                value = new String(os.toByteArray())
            }
            buffer.append(value);
        }

        // custom sectionData output
        @Override
        protected void appendDetail(StringBuffer buffer, String fieldName, Map<?, ?> map) {
            StringBuilder sb = new StringBuilder("{")
            if ('stringTable'.equals(fieldName)){
                map.each {
                    sb.append(String.format("%s%08X: %s",LINE_SEPARATOR, it.key, it.value))
                }
                buffer.append("${sb}}")
                return
            }

            if ('sectionData'.equals(fieldName)){
                map.each { it ->
                    String dump=''
                    if (it.value.length >0 ){
                        OutputStream os = new ByteArrayOutputStream()
                        HexDump.dump(it.value as byte[], 0, os, 0)
                        dump = new String(os.toByteArray())
                    }
                    sb.append "${it.key}=[${LINE_SEPARATOR}${dump}]${LINE_SEPARATOR}" as String
                }
                buffer.append(sb + LINE_SEPARATOR + '}')
                return
            }

            super.appendDetail(buffer, fieldName, map)
        }
    }
}


